﻿// -------------------------------------------------------------------------
//    @FileName         :    NFItemCreator.cpp
//    @Author           :    gaoyi
//    @Date             :    2024/12/17
//    @Email            :    445267987@qq.com
//    @Module           :    NFItemCreator
//
// -------------------------------------------------------------------------

#include "NFItemCreator.h"

#include <EquipStrengthDataDescEx.h>
#include <DescStore/EquipDesc.h>
#include <DescStore/EquipMagicCardDesc.h>
#include <DescStore/EquipStrengthDesc.h>
#include <DescStore/FashionDesc.h>
#include <DescStore/PartnerEquipDesc.h>
#include <NFComm/NFCore/NFRandom.hpp>
#include <NFComm/NFPluginModule/NFIKernelModule.h>

int NFItemCreator::CreatePartnerEquip(int iDescID, GridItemBase& base, PartnerEquipExt& equipData, int iDefaultQuality)
{
    LOGSVR_TRACE("begin " << iDescID << " quality: " << iDefaultQuality);
    auto pPartnerEquipDesc = PartnerEquipDesc::Instance()->GetDesc(iDescID);
    CHECK_NULL(0, pPartnerEquipDesc);

    memset(&base, 0, sizeof(base));
    memset(&equipData, 0, sizeof(equipData));

    // quality :
    // CHECK_EXPR( iDefaultQuality > 0 && iDefaultQuality < 6, proto_ff::ERR_CODE_INVALID_REQ_PARAM, "default quality error: " << iDefaultQuality );
    base.quality = pPartnerEquipDesc->quality;
    base.uuid = NFGlobalSystem::Instance()->GetGlobalPluginManager()->FindModule<NFIKernelModule>()->Get64UUID();
    base.id = iDescID;
    base.value = 1;
    equipData.base_attr_percent = RangeRand(1, 59);
    equipData.max_base_percent = equipData.base_attr_percent;

    CalcPartnerEquipCE(iDescID, base.quality, equipData);

    return 0;
}

int NFItemCreator::CreateEquip(int iDescID, GridItemBase& base, EquipExt& equipData, int iDefaultQuality)
{
    LOGSVR_TRACE("begin " << iDescID << " quality: " << iDefaultQuality );

    auto pEquipDesc = EquipDesc::Instance()->GetDesc(iDescID);
    CHECK_NULL(0, pEquipDesc);

    base.Init();
    equipData.Init();

    // quality :
    // CHECK_EXPR( iDefaultQuality > 0 && iDefaultQuality < 6, proto_ff::ERR_CODE_INVALID_REQ_PARAM, "default quality error: " << iDefaultQuality );
    base.quality = pEquipDesc->quality;

    base.uuid = NFGlobalSystem::Instance()->GetGlobalPluginManager()->FindModule<NFIKernelModule>()->Get64UUID();
    base.id = iDescID;
    base.value = 1;
    equipData.base_attr_percent = RangeRand( 1, 59 );
    equipData.max_base_percent = equipData.base_attr_percent;
    equipData.strength = pEquipDesc->strength_level;

    CalcEquipCE(iDescID, base.quality, equipData);

    return 0;
}

int NFItemCreator::CalcEquipCE(uint32_t iID, int iQuality, EquipExt& rEquip)
{
	auto pEquipDesc = EquipDesc::Instance()->GetDesc(iID);
	CHECK_NULL(0, pEquipDesc);

    const E_EquipStrength* pStrengthDesc = NULL;
    if(rEquip.strength > 0)
    {
        pStrengthDesc = EquipStrengthDataDescEx::Instance()->GetDesc(rEquip.strength, iID);
        if(!pStrengthDesc)
        {
            LOGSVR_ERROR("get desc err: " << iID << " strength: " << rEquip.strength);
        }
    }

    const int iSophisticatedVal = 90;
	const E_EquipMagicCard* magicDesc = 0;
	if(rEquip.magic_item > 0)
	{
		magicDesc = EquipMagicCardDesc::Instance()->GetDesc(rEquip.magic_item);
	}

    double lfCE = pEquipDesc->score * ( 0.002 * rEquip.base_attr_percent + ( rEquip.base_attr_percent >= iSophisticatedVal ? 0.85 : 0.8 ) ) ;

    double lfBaseCE = lfCE;
    if(pStrengthDesc)
    {
        lfCE += pStrengthDesc->score;
    }

    LOGSVR_DEBUG("get ce: " << lfCE << " id: " << iID << " score: " << pEquipDesc->score << " percent: " << rEquip.base_attr_percent);

	if(magicDesc)
	{
	   lfCE += magicDesc->score;
	}

	rEquip.job_ce.resize(proto_ff::enProfessionType_MAX);
    for(int i = 0; i < proto_ff::enProfessionType_MAX && i < (int)rEquip.job_ce.size(); ++i)
    {
        if(i == 1)
        {
            rEquip.job_ce[i] = (int)lfBaseCE;
        }
        else
        {
            rEquip.job_ce[i] = (int)lfCE;
        }
    }

	return 0;
}

int NFItemCreator::CalcPartnerEquipCE(uint32_t iID, int iQuality, PartnerEquipExt& rEquip)
{
    auto pPartnerEquipDesc = PartnerEquipDesc::Instance()->GetDesc(iID);
    CHECK_NULL(0, pPartnerEquipDesc);

    const int iSophisticatedVal = 90;
    double lfCE = pPartnerEquipDesc->score * ( 0.002 * rEquip.base_attr_percent + ( rEquip.base_attr_percent >= iSophisticatedVal ? 0.85 : 0.8 ) ) ;

    double lfBaseCE = lfCE;
    rEquip.job_ce.resize(proto_ff::enProfessionType_MAX);
    for(int i = 0; i < proto_ff::enProfessionType_MAX && i < (int)rEquip.job_ce.size() ; ++i)
    {
        if(i == 1)
        {
            rEquip.job_ce[i] = (int)lfBaseCE;
        }
        else
        {
            rEquip.job_ce[i] = (int)lfCE;
        }
    }
    return 0;
}

int NFItemCreator::CreateBuffEquip(int iDescID, GridItemBase& base, int iDefaultQuality)
{
    LOGSVR_TRACE("begin " << iDescID << " quality: " << iDefaultQuality);
    auto pBuffEquipDesc = ItemDesc::Instance()->GetDesc(iDescID);
    CHECK_NULL(0, pBuffEquipDesc);
    memset(&base, 0, sizeof(base));
    base.quality = 0;
    base.uuid = NFGlobalSystem::Instance()->GetGlobalPluginManager()->FindModule<NFIKernelModule>()->Get64UUID();
    base.id = iDescID;
    base.value = 1;

    return 0;
}

int NFItemCreator::CreateTreasureMap(int iDescID, GridItemBase& Base, TreasureMapExt& TreasureMapData)
{
    return 0;
}

int NFItemCreator::CreateItem(int iID, int iQuality, NFGridItem& item)
{
    auto pDesc = ItemDesc::Instance()->GetDesc(iID);
    CHECK_NULL(0, pDesc);

    int iRet = 0;
    item.m_iItemType = pDesc->item_type;
    switch (pDesc->item_type)
    {
        case proto_ff::EN_ITEM_TYPE_EQUIP:
        {
            item.m_uniExt.init_which_m_stData(NFGridItemExt_m_stEquip_tag);
            auto pExt = item.m_uniExt.get_m_stData_m_stEquip();
            CHECK_NULL(iID, pExt);
            iRet = CreateEquip(iID, item.m_stBase, *pExt, iQuality);
            CHECK_RET(iRet, "CreateEquip Error: {} {}", iRet, iID);
        }
        break;
        case proto_ff::EN_ITEM_TYPE_SKIN:
        {
            item.m_uniExt.init_which_m_stData(NFGridItemExt_m_stFashion_tag);
            auto pExt = item.m_uniExt.get_m_stData_m_stFashion();
            CHECK_NULL(iID, pExt);
            iRet = CreateFashion(iID, item.m_stBase, *pExt);
            CHECK_RET(iRet, "CreateFashion Error: {} {}", iRet, iID);
        }
        break;
        case proto_ff::EN_ITEM_TYPE_TREASUREMAP:
        {
            item.m_uniExt.init_which_m_stData(NFGridItemExt_m_stTreasureMap_tag);
            auto pExt = item.m_uniExt.get_m_stData_m_stTreasureMap();
            CHECK_NULL(iID, pExt);
            iRet = CreateTreasureMap(iID, item.m_stBase, *pExt);
            CHECK_RET(iRet, "CreateTreasureMap Error: {} {}", iRet, iID);
        }
        break;
        case proto_ff::EN_ITEM_TYPE_PARTNER_EQUIP:
        {
            item.m_uniExt.init_which_m_stData(NFGridItemExt_m_stPartnerEquip_tag);
            auto pExt = item.m_uniExt.get_m_stData_m_stPartnerEquip();
            CHECK_NULL(iID, pExt);
            iRet = CreatePartnerEquip(iID, item.m_stBase, *pExt, iQuality);
            CHECK_RET(iRet, "CreatePartnerEquip Error: {} {}", iRet, iID);
        }
        break;
        case proto_ff::EN_ITEM_TYPE_BUFF_EQUIP:
        {
            iRet = CreateBuffEquip(iID, item.m_stBase, iQuality);
            CHECK_RET(iRet, "CreateBuffEquip Error: {} {}", iRet, iID);
        }
        break;
        default:
            item.m_stBase.id = iID;
            item.m_stBase.quality = iQuality;
            item.m_stBase.value = 1;
            break;
    }

    if (pDesc->effective_time)
        item.m_stBase.effective_time = NF_ADJUST_TIMENOW() + pDesc->effective_time;

    if (pDesc->effective_end_time)
        item.m_stBase.effective_time = (item.m_stBase.effective_time == 0 || item.m_stBase.effective_time > pDesc->effective_end_time) ? pDesc->effective_end_time : item.m_stBase.effective_time;

    return 0;
}

int NFItemCreator::CreateFashion(int iDescID, GridItemBase& rBase, FashionExt& rFashionData)
{
    LOGSVR_TRACE("--begin " << iDescID << "--");

    auto desc = ItemDesc::Instance()->GetDesc(iDescID);
    CHECK_NULL(0, desc);

    auto pDesc = FashionDesc::Instance()->GetDesc(iDescID);
    CHECK_NULL(0, pDesc);

    rBase.Init();
    rFashionData.Init();

    if(pDesc->add_attr_count + pDesc->add_skill_count > 0)
        rFashionData.index_attr = rand() % (pDesc->add_attr_count + pDesc->add_skill_count);
    else
        rFashionData.index_attr = 0;

    if(pDesc->valid_time > 0)
    {
        rBase.effective_time = pDesc->valid_time + NF_ADJUST_TIMENOW();
    }

    rFashionData.free_count = 1;
    rBase.id = iDescID;
    rBase.value = 1;
    rBase.uuid = NFGlobalSystem::Instance()->GetGlobalPluginManager()->FindModule<NFIKernelModule>()->Get64UUID();

    LOGSVR_TRACE("--end--");

    return 0;
}
